#pragma once
#include <Types.h>
#include <BasicDagLibrary.h>
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void PrintPTRVectorToMMFile( const double * vec, const U64 nnz, const bool complex, const std::string mtxFileName );
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#ifdef __QTS__
void Pos2RowColQTSbd( U32 & r, U32 & c, U32 m, U32 n, U64 pos );
void Pos2RowColQTSad( U32 & r, U32 & c, U32 m, U32 n, U64 pos );
void Pos2RowColQTSod( U32 & r, U32 & c, U32 m, U32 n, U64 pos );
void Pos2RowColQTS( U32 & r, U32 & c, U32 m, U32 n, U64 pos );
U32 Pos2Row( const U64 _pos, const U32 _m, const U32 _n );
U32 Pos2Col( const U64 _pos, const U32 _m, const U32 _n );
#else
U32 Pos2Row( const U64 _pos, const U32 _m, const U32 _n );
U32 Pos2Col( const U64 _pos, const U32 _m, const U32 _n );
#endif

void SpMVCOO( const U64 hgt, const U32 m, const U32 n, const U64 * nodes, const double * x, double * y, const U32 numRuns, timespec * clks );
void SpMVCSR( const U64 nnzHgt, const U64 idxHgt, const U64 ptrHgt, const U32 m, const U32 n, const U64 nnz, const U64 * nodes, const double * x, double * y, const U32 numRuns, timespec * clks );

void SpMVRecursionKernelQTS( const U32 _lvl, const U32 _m, const U32 _n, const U64 _node, const U64 * _nodes, const double * _x, double * _y, const U64 _pos );
void SpMVFlatKernelCOO_HL2_final( const U32 _hgt, const U64 * _nodes, const U32 _nnzIdx0, const U32 _rcaIdx0, const U32 _nnzIdx1, const U32 _rcaIdx1, const double * _x, double * _y, timespec * clks );
void SpMVFlatKernelCOO( const U32 _hgt,  const U64 * _nodes, const double * _x, double * _y, timespec * clks );
void SpMVFlatKernelCOO_HL0( const U32 _hgt, const U64 * _nodes, const U32 _nnzIdx0, const U32 _rcaIdx0, const double * _x, double * _y, timespec * clks );
void SpMVFlatKernelCOO_HL2( const U32 _hgt, const U64 * _nodes, const U32 _nnzIdx0, const U32 _rcaIdx0, const U32 _nnzIdx1, const U32 _rcaIdx1, const double * _x, double * _y, timespec * clks );
void SpMVFlatKernelCOO_HL4( const U32 _hgt, const U64 * _nodes, const U32 _nnzIdx0, const U32 _rcaIdx0, const U32 _nnzIdx1, const U32 _rcaIdx1, const U32 _nnzIdx2, const U32 _rcaIdx2, const U32 _nnzIdx3, const U32 _rcaIdx3, const double * _x, double * _y, timespec * clks );
void SpMVFlatKernelCOO_HL8( const U32 _hgt, const U64 * _nodes, const U32 _nnzIdx0, const U32 _rcaIdx0, 
                                                                const U32 _nnzIdx1, const U32 _rcaIdx1,
                                                                const U32 _nnzIdx2, const U32 _rcaIdx2,
                                                                const U32 _nnzIdx3, const U32 _rcaIdx3,
                                                                const U32 _nnzIdx4, const U32 _rcaIdx4,
                                                                const U32 _nnzIdx5, const U32 _rcaIdx5,
                                                                const U32 _nnzIdx6, const U32 _rcaIdx6,
                                                                const U32 _nnzIdx7, const U32 _rcaIdx7,
                                                                const double * _x, double * _y, timespec * clks );
                                                                
void SpMVFlatKernelCOO_HL16( const U32 _hgt, const U64 * _nodes, const U32 _nnzIdx0, const U32 _rcaIdx0, 
                                                                 const U32 _nnzIdx1, const U32 _rcaIdx1,
                                                                 const U32 _nnzIdx2, const U32 _rcaIdx2,
                                                                 const U32 _nnzIdx3, const U32 _rcaIdx3,
                                                                 const U32 _nnzIdx4, const U32 _rcaIdx4,
                                                                 const U32 _nnzIdx5, const U32 _rcaIdx5,
                                                                 const U32 _nnzIdx6, const U32 _rcaIdx6,
                                                                 const U32 _nnzIdx7, const U32 _rcaIdx7,
                                                                 const U32 _nnzIdx8, const U32 _rcaIdx8,
                                                                 const U32 _nnzIdx9, const U32 _rcaIdx9,
                                                                 const U32 _nnzIdxA, const U32 _rcaIdxA,
                                                                 const U32 _nnzIdxB, const U32 _rcaIdxB,
                                                                 const U32 _nnzIdxC, const U32 _rcaIdxC,
                                                                 const U32 _nnzIdxD, const U32 _rcaIdxD,
                                                                 const U32 _nnzIdxE, const U32 _rcaIdxE,
                                                                 const U32 _nnzIdxF, const U32 _rcaIdxF,
                                                                 const double * _x, double * _y, timespec * clks );
void SpMVFlatKernelCSR( const U64 _nnz, const U64 _m, const U32 _nnzHgt, const U32 _idxHgt, const U32 _ptrHgt, const U64 * _nodes,
                        const U32 _nnzValsRootNodePtr,
                        const U32 _colIdxsRootNodePtr,
                        const U32 _rowPtrsRootNodePtr,
                        const double * x, double * y, timespec * clks );
